package org.boot.easyapi.file.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.boot.easyapi.file.config.FileStorageConfig;
import org.boot.easyapi.file.dao.FileInfoRepository;
import org.boot.easyapi.file.entity.FileInfoDO;
import org.boot.easyapi.file.service.FileUploadService;
import org.boot.easyapi.file.util.MimeMapping;
import org.boot.easyapi.pojo.web.CommonResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.boot.easyapi.pojo.web.CommonResult.success;

@Tag(name = "EasyApi - 文件管理")
@RestController
@RequestMapping("/easyapi/file")
public class FileUploadController {

    @Resource
    private FileStorageConfig fileStorageConfig;

    @Resource
    private FileUploadService fileInfoService;

    @Resource
    private FileInfoRepository fileInfoRepository;

    @PostMapping("/upload")
    @Operation(summary = "文件上传")
    public CommonResult<Long> upload(@RequestParam("file") MultipartFile file) {
        return success(fileInfoService.upload(file).getId());
    }

    @DeleteMapping("/delete")
    @Operation(summary = "文件删除")
    public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
        /* 1. 查数据库 */
        FileInfoDO fileInfo = fileInfoRepository.findById(id);
        if (fileInfo == null) {
            throw new RuntimeException("文件记录不存在！");
        }
        /* 2. 拼物理路径并校验 */
        String rootPath = fileStorageConfig.getRootPath();
        if (rootPath == null || rootPath.trim().isEmpty()) {
            throw new RuntimeException("文件根路径未配置！");
        }
        Path path = Paths.get(fileInfo.getFilePath());
        try {
            /* 3. 先删磁盘 */
            if (Files.exists(path)) {
                Files.delete(path);
            }
            /* 4. 再删数据库 */
            fileInfoRepository.deleteById(id);
        } catch (IOException e) {
            throw new RuntimeException("删除磁盘文件失败", e);
        } catch (Exception e) {
            throw new RuntimeException("删除数据库记录失败", e);
        }
        return success(true);
    }

    @GetMapping("/download")
    @Operation(summary = "文件下载")
    public void download(@RequestParam("id") Long id, HttpServletResponse response) {
        FileInfoDO fileInfo = fileInfoRepository.findById(id);
        if (fileInfo == null) {
            throw new RuntimeException("文件不存在！");
        }
        try{
            response.setContentType("application/force-download");// 设置强制下载不打开
            response.addHeader("Content-Disposition","attachment;fileName="
                    + new String(fileInfo.getFileName().getBytes("UTF-8"),"iso-8859-1"));

            // ------------------------------附件读取--------------------------------------------------
            String rootPath = fileStorageConfig.getRootPath();
            if (rootPath == null || rootPath.trim().isEmpty()) {
                throw new RuntimeException("文件根路径未配置！");
            }
            Path path = Paths.get(fileInfo.getFilePath());
            if (!Files.exists(path)) {
                throw new RuntimeException("文件物理路径不存在！");
            }
            //读取文件，获取byte[]
            byte[] bytes = Files.readAllBytes(path);
            response.getOutputStream().write(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/preview")
    @Operation(summary = "文件预览")
    public void preview(@RequestParam("id") Long id,
                            HttpServletResponse response) {
        FileInfoDO fileInfo = fileInfoRepository.findById(id);
        if (fileInfo == null) {
            throw new RuntimeException("文件不存在！");
        }

        String fileName = fileInfo.getFileName();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        String mimeType = MimeMapping.getMimeType(suffix);   // 获取MIME类型
        if (mimeType == null) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            throw new RuntimeException("不支持的预览格式");
        }
        response.setContentType(mimeType);
        response.setCharacterEncoding("UTF-8");

        /* 2. 缓存控制，可按需调整 */
        response.setHeader("Cache-Control", "max-age=3600");

        /* 3. 输出文件流 */
        String rootPath = fileStorageConfig.getRootPath();
        if (rootPath == null || rootPath.trim().isEmpty()) {
            throw new RuntimeException("文件路径不存在！");
        }
        Path path = Paths.get(fileInfo.getFilePath());
        if (!Files.exists(path)) {
            throw new RuntimeException("文件物理路径不存在！");
        }

        try (ServletOutputStream out = response.getOutputStream()) {
            Files.copy(path, out);
            out.flush();
        } catch (IOException e) {
            throw new RuntimeException("预览文件失败", e);
        }
    }

}
